/**
/**
 * @file heibot.h
 * @author hellokun (www.hellokun.cn)
 * @brief
 * @version 0.1 ，关闭oled显示，提升NAN配网成功率；先初始化mpu等，再启动NAN；控制大量使用switch 配合return实现较快响应
 * @date
 *       2021.12-2022.04: 南北向基础
 *       2022.03.16: 实现基础运动控制
 *       2022.04-05：APP UI 与硬件联动
 *      Tips：关闭oled显示，NAN效率更高，开机实现不到一秒连接
 * @copyright Copyright (c) 2022
 *
 */
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "securec.h"
#include "ohos_types.h"

#include "touch_sensor.h"
#include "bluetooth.h"
#include "speaker.h"
#include "motor.h"
#include "oled_ssd1306.h"
#include "netcfg.h"
#include "network_config_service.h"
#include "defines.h"
#include "mrobot.h"
#include "mpu6050.h"

#define TICKS_NUMBER (100) // 1 ticks = 10ms
#define TIMER_ONE_HOUR 60
#define TIMER_MAX_HOURS 8
#define TIMER_60_SECOND 60
#define MESSAGE_LEN 6
#define circle_time 1000000 //机器人一次运动时间
typedef struct
{

    uint8 robot_reset;
    uint8 move_forward;
    uint8 move_backward;
    uint8 move_left;
    uint8 move_right;

    uint8 ctr_fan;
    uint8 ctr_door;
    uint8 ctr_lamb;
    uint8 ctr_water;

    char app_msg[100];

    bool timer_flag;

    uint8 timer_hour;
    uint8 timer_mins;
    uint32 timer_count;

    osTimerId_t timerID;
} MrobotInfo;
static MrobotInfo m_robot;
static bool m_netstatus = false;
char app_msg[12] = {'0'};

unsigned char ble_send_data[12] = {'0'}; //蓝牙发送缓冲
unsigned char get_ble_data[8] = {'0'};   //蓝牙接收缓存

unsigned char mrobot2sut03[] = {0xAA, 0x55, 0x00, 0x55, 0xAA};
unsigned char sut032mrobot[] = {0xAA, 0x55, 0x00, 0x55, 0xAA};
unsigned char mrobot2fan[] = {'1', '0'};
unsigned char mrobot2door[] = {'2', '0'};
unsigned char mrobot2lamb[] = {'3', '0'};
unsigned char mrobot2water[] = {'4', '0'}; //默认关闭

short aacx, aacy, aacz;    //加速度传感器原始数据
short gyrox, gyroy, gyroz; //陀螺仪原始数据
int mpu_temp;          //陀螺仪本身自带温度传感

static void MRobotTimerHandler(void *arg)
{
    (void)arg;

    if (m_robot.timer_flag)
    {
        m_robot.timer_count++;
        if (m_robot.timer_count >= (uint32)((m_robot.timer_hour * (TIMER_60_SECOND * TIMER_60_SECOND)) +
                                            m_robot.timer_mins * TIMER_60_SECOND))
        {
            m_robot.robot_reset = 1;
        }
    }
    else
    {
        m_robot.timer_count = 0;
    }
}

static void MRobotStartTimer(void)
{
    m_robot.timerID = osTimerNew(&MRobotTimerHandler, osTimerPeriodic, NULL, NULL);
    osTimerStart(m_robot.timerID, TICKS_NUMBER);
}

static void MRobotProcessAppMessage(const char *data, int data_len)
{
    if (data_len != MESSAGE_LEN)
    {
        strcpy(app_msg, data);
        // app_msg=data;
        printf("------app_msg:%s \r\n", app_msg);
        printf("----- data:%s\r\n", data);
        WINERR("data len invalid! \n");
        return;
    }
}

static int MRobotNetEventHandler(NET_EVENT_TYPE event, void *data)
{
    switch (event)
    {
    case NET_EVENT_CONNECTTED: // 网络连接成功
        m_netstatus = true;
        printf("m_netstatus:%d\n\n", m_netstatus); // 显示网络已连接
        break;
    case NET_EVENT_RECV_DATA:                                      // 接收到网络信息(FA发送的消息)
        MRobotProcessAppMessage((const char *)data, strlen(data)); // 处理对应的信息
        break;
    default:
        break;
    }
    return 0;
}

//严格按照【自定义MRobot与互联设备间数据帧.txt】判断数据
// app运动控制
static void AppCtrMRobot()
{
    switch (*app_msg)
    {
    case 'F':
    {
        printf("退下\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Forward", 2);
        Backward(circle_time);
        Stop_motor();
        return; //每次仅有一种情况，满足直接return回main
    }
    case 'B':
    {
        printf("过来\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Backward", 2);
        Forward(circle_time);
        Stop_motor();
        return;
    }
    case 'L':
    {
        printf("左转\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Turn Left", 2);
        Turn_left(circle_time);
        Stop_motor();
        return;
    }
    case 'R':
    {
        printf("右转\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Turn Right", 2);
        Turn_right(circle_time);
        Stop_motor();
        return;
    }
    case 'C':
    {
        printf("转圈\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Circle running", 2);
        Circle(circle_time);
        Stop_motor();
        return;
    }
    default:
    {
        return;
    }
    }
}

// speaker运动控制
static void SpeakerCtrMRobot()
{
    switch (sut032mrobot[2])
    {
    case 0x03:
    {
        printf("过来\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Forward", 2);
        Forward(circle_time);
        Stop_motor();
        return;
    }
    case 0x04:
    {
        printf("退下\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Backward", 2);
        Backward(circle_time);
        Stop_motor();
        return;
    }
    case 0x01:
    {
        printf("左转\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Turn Left", 2);
        Turn_left(circle_time);
        Stop_motor();
        return;
    }
    case 0x02:
    {
        printf("右转\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Turn Right", 2);
        Turn_right(circle_time);
        Stop_motor();
        return;
    }
    case 0x05:
    {
        printf("转圈\r\n");
        // OledFillScreen(0x00);
        // OledShowString(25, 2, "Circle running", 2);
        Circle(circle_time);
        Stop_motor();
        return;
    }
    default:
    {
        return;
    }
    }
}
//其他互联设备【风扇、门锁、台灯、养花机】控制
static void UnionDeviceCtr()
{
    switch (sut032mrobot[2])
    {
    case 0x91:
    {
        mrobot2fan[1] = '1';
        printf("turn on fan\n");
        Bluetooth_write(mrobot2fan, 2);
        break;
    }
    case 0x90:
    {
        printf("turn of fan\n");
        mrobot2fan[1] = '0';
        Bluetooth_write(mrobot2fan, 2);
        break;
    }
    case 0x81:
    {
        mrobot2door[1] = '1';
        Bluetooth_write(mrobot2door, 2);
        break;
    }
    case 0x71:
    {
        mrobot2lamb[1] = '1';
        Bluetooth_write(mrobot2lamb, 2);
        break;
    }
    case 0x70:
    {
        mrobot2lamb[1] = '0';
        Bluetooth_write(mrobot2lamb, 2);
        break;
    }
    case 0x61:
    {
        mrobot2water[1] = '1';
        Bluetooth_write(mrobot2water, 2);
        break;
    }
    case 0x51: //获取温度
    {
        Bluetooth_write("51", 2);
        break;
    }
    default:
    {
        break;
    }
    }
    if (strcmp(app_msg, "turn on fan") == 0)
    {
        mrobot2fan[1] = '1';
        Bluetooth_write(mrobot2fan, 2);
        return;
    }
    if (strcmp(app_msg, "turn off fan") == 0)
    {
        mrobot2fan[1] = '0';
        Bluetooth_write(mrobot2fan, 2);
        return;
    }
    if (strcmp(app_msg, "open door") == 0)
    {
        mrobot2door[1] = '1';
        Bluetooth_write(mrobot2door, 2);
        return;
    }
    if (strcmp(app_msg, "turn on lamb") == 0)
    {
        mrobot2lamb[1] = '1';
        Bluetooth_write(mrobot2lamb, 2);
        return;
    }
    if (strcmp(app_msg, "turn off lamb") == 0)
    {
        mrobot2lamb[1] = '0';
        Bluetooth_write(mrobot2lamb, 2);
        return;
    }
    if (strcmp(app_msg, "go ahead water") == 0)
    {
        mrobot2water[1] = '1';
        Bluetooth_write(mrobot2water, 2);
        return;
    }
    return;
}

// sut03交互
static void AppMsg2Speaker()
{
    switch (*app_msg)
    {
    case '1':
    {
        mrobot2sut03[2] = 0x01;
        break;
    }
    case '2':
    {
        mrobot2sut03[2] = 0x02;
        break;
    }
    case '3':
    {
        mrobot2sut03[2] = 0x03;
        break;
    }
    case '4':
    {
        mrobot2sut03[2] = 0x04;
        break;
    }
    case '5':
    {
        mrobot2sut03[2] = 0x05;
        break;
    }
    case '6':
    {
        mrobot2sut03[2] = 0x06;
        break;
    }
    case '7':
    {
        mrobot2sut03[2] = 0x07;
        break;
    }
    case '8':
    {
        mrobot2sut03[2] = 0x08;
        break;
    }
    default:
    {
        return; //不播报
    }
    }
    Bluetooth_write(mrobot2sut03, SUT03_LEN);
    return;
}

static void MRobot_Init()
{
    if (Bluetooth_Init() >= 0)
    {
        printf("Bluetooth initial successful\n");
    }
    if (Speaker_Init() >= 0)
    {
        printf("Speaker initial successful\n");
    }

    TouchSensorInit();
    Motor_Init();
   //MPU_Init(); //返回0 成功
    /*while (MPU_Init())
    {
        printf("MPU Initialize Faild \n");
    }*/
    // MPU_Init()与Oled同时只能使用一个
    // OledInit();

    // OledFillScreen(0x00);
    // OledShowString(25, 2, "Hello", 2); //==位置、内容、大小1、2可选
    // sleep(2);
    // OledFillScreen(0x00);
    // OledShowString(30, 2, "Kun", 2); //==位置、内容、大小1、2可选
    // sleep(1);
    // OledFillScreen(0x00);
    // OledShowString(25, 2, "HarmonyOS", 2); //==位置、内容、大小1、2可选
    // sleep(2);
    // OledFillScreen(0x00);

    // OledFillScreen(0x00);
    // for (int y = 0; y < 1; y++)
    // {
    //     OledShowString(0, y, "Hello,HarmonyOS", 2); //==位置、内容、大小1、2可选
    // }
    // sleep(1);
    // OledFillScreen(0x00);
    // OledShowString(25, 2, "I am HeiBot", 2);
}

static void *MRobotTask(const char *arg)
{
    (void)arg;
    MRobot_Init();
    MRobotStartTimer();                    // 开启定时器
    NetCfgRegister(MRobotNetEventHandler); // 进入配网状态并注册网络监听事件

    int ret;

    // 温度数据说明
    // DATA: AA 55 01 20 06 55 AA
    // Format      head + index + data_H data_L + tail
    // char *head="AA55";
    // char *tail="55AA";
    // strcat(head,S_TAIL);
    // sut03 下发指令给hi3861，hi3861发送请求给 温度采集设备，设备反向上报数据。
    double GetTemperature = 20;
    unsigned char temperature_H[] = {0x16};                                        //采集温度
    unsigned char temperature_L[] = {0x08};                                        //采集温度
    unsigned char temperature_data[] = {0xAA, 0x55, 0x09, 0x16, 0x08, 0x55, 0xAA}; //  0x16, 0x08, 22.8℃

    float touch_val = 0;
    while (1)
    {
        //mpu_temp = MPU_Get_Temperature();
        //MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);
        //MPU_Get_Accelerometer(&aacx,&aacy,&aacz);
        touch_val = Get_touch_val();
        // printf("touch_val= %.3f \n", touch_val);
       
        // Speaker_read(sut032mrobot, CMD_LEN); //实时获取语音识别结果
        // printf("sut032mrobot:%s \n", sut032mrobot);
        // if (sut032mrobot[5] == 0x01) // AA550 1 55AA
        // {
        //     Turn_right(circle_time);
        //     Stop_motor();
        // }
        //Print_Original_MPU_Data();
        //printf("loop temperature = %d \n",mpu_temp);
        if (touch_val >130 |gyrox<20) //gyrox实际数值与安装有关。
        {
            // OledFillScreen(0x00);
            // OledShowSmile(0, 0, 31);

            // Bluetooth_write(temperature_data, TEMP_LEN);
            mrobot2sut03[2] = 0x01; //喵喵喵
            Bluetooth_write(mrobot2sut03, SUT03_LEN);
            // Speaker_write(mrobot2sut03, SUT03_LEN);
        }
        ret = Bluetooth_read(sut032mrobot, 5);
        printf("ret bluetooth read:  %d \n", ret);
        //printf("sut032mrobot:%0x \n", sut032mrobot);

        if (sut032mrobot[2] != 0x00)
        {
            SpeakerCtrMRobot();
        }
        if (app_msg[0] != '0')
        {
            AppCtrMRobot();
            AppMsg2Speaker();
        }
        if ((sut032mrobot[2] != 0x00) | (app_msg[0] != '0'))
        {
            UnionDeviceCtr();
        }
        //循环之前置为初始化
        app_msg[0] = '0';
        get_ble_data[0] = '0';
        sut032mrobot[2] = 0x00;
        osDelay(200);
    }
}

static void MRobotEntry(void)
{
    osThreadAttr_t attr;
    attr.name = "MRobotTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;
    attr.priority = 25;

    if (osThreadNew(MRobotTask, NULL, &attr) == NULL)
    {
        printf("[MRobotTask] Falied to create HeibotTask!\n");
    }
}
// APP_FEATURE_INIT(MRobotEntry);
SYS_RUN(MRobotEntry);